namespace jsWrite {
    interface eventsType {
        [Indexes:string]:Array<(...arg:Array<any>)=>void>
    }
    class EventEmitter {
        private events:eventsType
        constructor(){
            this.events = {};
        }
        on(eventName:string,callback:(...arg:Array<any>)=>void){
            let callbacks = this.events[eventName] || [];
            callbacks.push(callback);
            this.events[eventName] = callbacks;
        }
        emit(eventName:string,...args:Array<any>){
            if(!this.events[eventName]) return;
            this.events[eventName].forEach(cb=>cb(...args));
        }
        off(eventName:string,callback:(...arg:Array<any>)=>void){
            if(!this.events[eventName]) return;
            this.events[eventName] = this.events[eventName].filter(cb=>cb!==callback);
        }
        once(eventName:string,callback:(...arg:Array<any>)=>void){
            let _this:EventEmitter = this;
            this.on(eventName,function fun(...args:Array<any>){
                callback(...args);
                _this.off(eventName,fun);
            });
        }
    }

    let eve = new EventEmitter();
    eve.on('xy',(a=111)=>{console.log(a)});
    eve.on('xy',(a=111)=>{console.log(a+1)});
    eve.once('yx',()=>{console.log('历神')});
    eve.emit('xy',3333);
    eve.emit('yx');
    eve.emit('yx');
}